home *** CD-ROM | disk | FTP | other *** search
- /* Midnight Commander Tk initialization and main loop
- Copyright (C) 1995 Miguel de Icaza
- Copyright (C) 1995 Jakub Jelinek
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /*
- * The Tk version of the code tries to use as much code as possible
- * from the curses version of the code, so we Tk as barely as possible
- * and manage most of the events ourselves. This may cause some
- * confusion at the beginning.
- */
-
- #include <config.h>
- #include <stdarg.h>
- #include <string.h>
- #include <ctype.h>
- #include "tkmain.h"
- #include "key.h"
- #include "global.h"
- #include "tty.h" /* for KEY_BACKSPACE */
-
- /* Tcl interpreter */
- Tcl_Interp *interp;
-
- /* if true, it's like mc, otherwise is like mxc */
- int use_one_window = 1;
-
- static char *display = NULL;
-
- /* Used to quote the next character, emulates mi_getch () */
- static int mi_getch_waiting = 0;
- static int mi_getch_value;
-
- static Tk_ArgvInfo arg_table[] = {
- {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display,
- "Display to use"},
- {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL,
- (char *) NULL}
- };
-
- static int tkmc_callback (ClientData cd, Tcl_Interp *i, int ac, char *av[]);
-
- int
- xtoolkit_init (int *argc, char *argv[])
- {
- interp = Tcl_CreateInterp ();
- if (Tk_ParseArgv (interp, (Tk_Window) NULL, argc, argv, arg_table, 0)
- != TCL_OK) {
- fprintf(stderr, "%s\n", interp->result);
- exit(1);
- }
-
- /* Pass DISPLAY variable to child procedures */
- if (display != NULL) {
- Tcl_SetVar2 (interp, "env", "DISPLAY", display, TCL_GLOBAL_ONLY);
- }
-
- Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
-
- Tcl_SetVar(interp, "one_window",
- use_one_window ? "1" : "0", TCL_GLOBAL_ONLY);
-
- /*
- * Initialize the Tk application.
- */
- #ifdef OLD_VERSION
- tkwin = Tk_CreateMainWindow (interp, display, "Midnight Commander","tkmc");
- #endif
- if (Tcl_Init (interp) != TCL_OK){
- fprintf (stderr, "%s\n", interp->result);
- exit (1);
- }
- if (Tk_Init (interp) != TCL_OK){
- fprintf (stderr, "%s\n", interp->result);
- exit (1);
- }
-
- Tcl_CreateCommand (interp, "tkmc", tkmc_callback, 0, 0);
- if (Tcl_EvalFile (interp, LIBDIR "mc.tcl") == TCL_OK)
- return 0;
- else {
- printf ("%s\n", interp->result);
- exit (1);
- }
- }
-
- int
- xtoolkit_end (void)
- {
- /* Cleanup */
- Tcl_Eval (interp, "exit");
- return 1;
- }
-
- void
- tk_evalf (char *format, ...)
- {
- va_list ap;
- char buffer [1024];
-
- va_start (ap, format);
- vsprintf (buffer, format, ap);
- if (Tcl_Eval (interp, buffer) != TCL_OK){
- fprintf (stderr, "[%s]: %s\n", buffer, interp->result);
- }
- va_end (ap);
- }
-
- int
- tk_evalf_val (char *format, ...)
- {
- va_list ap;
- char buffer [1024];
- int r;
-
- va_start (ap, format);
- vsprintf (buffer, format, ap);
- r = Tcl_Eval (interp, buffer);
- va_end (ap);
- return r;
- }
-
- widget_data
- xtoolkit_create_dialog (Dlg_head *h)
- {
- char *dialog_name = copy_strings (".", h->name, 0);
-
- tk_evalf ("toplevel %s", dialog_name);
- return (widget_data) dialog_name;
- }
-
- void
- x_set_dialog_title (Dlg_head *h, char *title)
- {
- tk_evalf ("wm title %s {%s}", (char *)(h->wdata), title);
- }
-
- widget_data
- xtoolkit_get_main_dialog (Dlg_head *h)
- {
- return (widget_data) strdup (".");
- }
-
- /* Creates the containers */
- widget_data
- x_create_panel_container (int which)
- {
- char *s, *cmd;
-
- cmd = use_one_window ? "frame" : "toplevel";
- s = which ? ".right" : ".left";
- tk_evalf ("%s %s", cmd, s);
-
- return (widget_data) s;
- }
-
- void
- x_panel_container_show (widget_data wdata)
- {
- }
-
- int
- do_esc_key (int d)
- {
- if (isdigit(d))
- return KEY_F(d-'0');
- if ((d >= 'a' && d <= 'z') || (d >= 'A' && d <= 'Z' )
- || d == '\n' || d == '\t' || d == XCTRL ('h') || d == '!'
- || d == KEY_BACKSPACE || d == 127 || d == '\r')
- return ALT(d);
- else {
- return ESC_CHAR;
- }
- }
-
- /* This commands has this sintax:
- * [r|a|c] ascii
- *
- * r, a, c, k: regular, alt, control, keysym
- */
-
- static int
- tkmc_callback (ClientData cd, Tcl_Interp *i, int ac, char *av[])
- {
- Dlg_head *h = current_dlg;
- int key;
- static int got_esc;
-
- key = av [2][0];
-
- if (av [1][0] == 'c' || av [1][0] == 'a'){
- if (!key)
- return TCL_OK;
-
- /* Regular? */
-
- if (!isascii (key)){
- return TCL_OK;
- } else {
- key = tolower (key);
- }
- }
-
- switch (av [1][0]){
- case 'a':
- key = ALT(key);
- break;
-
- case 'c':
- key = XCTRL(key);
- break;
-
- case 'r':
- if (!key)
- return TCL_OK;
- break;
-
- case 'k':
- if (!(key = lookup_keysym (av [2])))
- return TCL_OK;
- break;
- }
-
- if (key == '\r')
- key = '\n';
-
- if (key == ESC_CHAR){
- if (!got_esc){
- got_esc = 1;
- return TCL_OK;
- }
- got_esc = 0;
- }
-
- if (got_esc){
- key = do_esc_key (key);
- got_esc = 0;
- }
-
- if (mi_getch_waiting && key){
- mi_getch_waiting = 0;
- mi_getch_value = key;
- return TCL_OK;
- }
- dlg_key_event (h, key);
- update_cursor (h);
- return TCL_OK;
- }
-
- void
- tk_focus_widget (Widget_Item *p)
- {
- char *wname;
-
- if (!p->widget)
- return;
-
- wname = (char *) p->widget->wdata;
-
- if (!wname)
- return;
-
- tk_evalf ("focus %s", wname+1);
- }
-
- /* This routine uses the grid geometry manager to layout
- * the widgets inside the dialog. This is called if no
- * layout routine has been defined for the window
- * it also calls a post layout routine to spice up the dialog
- */
- void
- do_grid_layout (Dlg_head *h, char *wname)
- {
- const int cols = h->cols;
- const int lines = h->lines;
- const int widgets = h->count;
- const int wherex = h->x;
- const int wherey = h->y;
- Widget_Item *h_track;
- int i, height, width;
-
- #if 0
- for (i = 0; i < cols; i++){
- int j;
-
- for (j = 0; j < lines; j++){
- tk_evalf ("frame %s.f%d-%d -height 18 -width 10", wname, i, j);
- tk_evalf ("grid configure %s.f%d-%d -row %d -column %d", wname, i, j, j, i);
- }
- }
- #endif
- tk_evalf_val ("set $setup(heightc)");
- height = atoi (interp->result) * 2;
- tk_evalf_val ("set $setup(widthc)");
- width = atoi (interp->result) *2;
-
- if (height == 0 || width == 0){
- fprintf (stderr, "valiste verga\n");
- height = 30;
- width = 20;
- }
- h_track = h->current;
- for (i = 0; i < widgets; i++){
- fprintf (stderr, "%s goes to: %d %d\n\r", (char *) h_track->widget->wdata,
- h_track->widget->x - wherex, h_track->widget->y-wherey);
- tk_evalf ("place configure %s -x %d -y %d ",
- ((char *) (h_track->widget->wdata))+1,
- (h_track->widget->x - wherex) * width,
- (h_track->widget->y - wherey) * height);
- h_track = h_track->prev;
- }
- }
-
- /* Setup done before using tkrundlg_event */
- void
- tk_init_dlg (Dlg_head *h)
- {
- Widget_Item *h_track;
- char *wname;
- int i;
-
- /* Set wlist to hold all the widget names that will be ran */
- tk_evalf ("set wlist {}");
- h_track = h->current;
- for (i = 0; i < h->count; i++){
- char *wname = (char *)h_track->widget->wdata;
- if (wname)
- tk_evalf ("set wlist \"%s $wlist\"", wname+1);
- h_track = h_track->prev;
- }
-
- wname = (char *) h->wdata;
-
- /* Layout the window, if no layout routine is defined, use grided layout */
- if (tk_evalf_val ("layout_%s", h->name) != TCL_OK)
- do_grid_layout (h, wname);
-
- /* setup window bindings */
- tk_evalf ("bind_setup %s", wname);
-
- /* If this is not the main window, center it */
- if (wname [0] && wname [1]){
- tk_evalf ("center_win %s", wname);
- }
- }
-
- int
- tkrundlg_event (Dlg_head *h)
- {
- /* Run the dialog */
- while (h->running){
- if (h->send_idle_msg){
- if (Tcl_DoOneEvent (TCL_DONT_WAIT))
- if (idle_hook)
- execute_hooks (idle_hook);
-
- while (Tcl_DoOneEvent (TCL_DONT_WAIT) &&
- h->running && h->send_idle_msg){
- (*h->callback) (h, 0, DLG_IDLE);
- }
- } else
- Tcl_DoOneEvent (TCL_ALL_EVENTS);
- }
-
- return 1;
- }
-
- int
- Tcl_AppInit (Tcl_Interp *interp)
- {
- return TCL_OK;
- }
-
- void
- x_interactive_display ()
- {
- }
-
- int
- tk_getch ()
- {
- mi_getch_waiting = 1;
-
- while (mi_getch_waiting)
- Tk_DoOneEvent (TK_ALL_EVENTS);
-
- return mi_getch_value;
- }
-
- void
- tk_dispatch_all (void)
- {
- while (Tk_DoOneEvent (TK_DONT_WAIT))
- ;
- }
-